import { ApiProperty } from '@nestjs/swagger'
import { Type } from 'class-transformer'
import { IsOptional, IsInt, Min, Max, IsString, IsEnum } from 'class-validator'

/**
 * 排序方向枚举
 */
export enum SortOrder {
  ASC = 'asc',
  DESC = 'desc'
}

/**
 * 分页查询DTO
 */
export class PaginationDto {
  @ApiProperty({
    description: '页码',
    minimum: 1,
    default: 1,
    required: false
  })
  @IsOptional()
  @Type(() => Number)
  @IsInt({ message: '页码必须是整数' })
  @Min(1, { message: '页码不能小于1' })
  page?: number = 1

  @ApiProperty({
    description: '每页数量',
    minimum: 1,
    maximum: 100,
    default: 10,
    required: false
  })
  @IsOptional()
  @Type(() => Number)
  @IsInt({ message: '每页数量必须是整数' })
  @Min(1, { message: '每页数量不能小于1' })
  @Max(100, { message: '每页数量不能超过100' })
  limit?: number = 10

  @ApiProperty({
    description: '排序字段',
    required: false
  })
  @IsOptional()
  @IsString({ message: '排序字段必须是字符串' })
  sortBy?: string

  @ApiProperty({
    description: '排序方向',
    enum: SortOrder,
    default: SortOrder.DESC,
    required: false
  })
  @IsOptional()
  @IsEnum(SortOrder, { message: '排序方向必须是asc或desc' })
  sortOrder?: SortOrder = SortOrder.DESC

  @ApiProperty({
    description: '搜索关键词',
    required: false
  })
  @IsOptional()
  @IsString({ message: '搜索关键词必须是字符串' })
  search?: string
}

/**
 * 分页响应DTO
 */
export class PaginatedResponseDto<T> {
  @ApiProperty({ description: '数据列表' })
  data: T[]

  @ApiProperty({ description: '总数量' })
  total: number

  @ApiProperty({ description: '当前页码' })
  page: number

  @ApiProperty({ description: '每页数量' })
  limit: number

  @ApiProperty({ description: '总页数' })
  totalPages: number

  @ApiProperty({ description: '是否有下一页' })
  hasNext: boolean

  @ApiProperty({ description: '是否有上一页' })
  hasPrev: boolean

  constructor(data: T[], total: number, page: number, limit: number) {
    this.data = data
    this.total = total
    this.page = page
    this.limit = limit
    this.totalPages = Math.ceil(total / limit)
    this.hasNext = page < this.totalPages
    this.hasPrev = page > 1
  }
}
